package com.koron.order.overhaul.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.koron.bean.query.OrderItem;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.workflow.RedirectQuery;
import com.koron.common.core.business.workflow.templates.WorkFlowHandler;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.order.common.bean.base.OrderType;
import com.koron.order.common.bean.po.*;
import com.koron.order.common.bean.vo.OrderExecuteVo;
import com.koron.order.common.mapper.OrderSignMapper;
import com.koron.order.common.service.*;
import com.koron.order.experiment.bean.query.ExperimentQuery;
import com.koron.order.experiment.bean.vo.ExperimentVo;
import com.koron.order.experiment.service.ExperimentService;
import com.koron.order.grade.bean.entity.OrderGradeBean;
import com.koron.order.grade.service.OrderGradeService;
import com.koron.order.overhaul.bean.convertor.OverhaulOrderConvertor;
import com.koron.order.overhaul.bean.dto.*;
import com.koron.order.overhaul.bean.entity.OverhaulOrderBean;
import com.koron.order.overhaul.bean.entity.OverhaulOrderItemBean;
import com.koron.order.overhaul.bean.entity.OverhaulOrderReportBean;
import com.koron.order.overhaul.bean.query.OverhaulExperimentQuery;
import com.koron.order.overhaul.bean.query.OverhaulOrderQuery;
import com.koron.order.overhaul.bean.vo.*;
import com.koron.order.overhaul.feign.EquipmentFeign;
import com.koron.order.overhaul.feign.GradeFeign;
import com.koron.order.overhaul.feign.PlanIssueFeign;
import com.koron.order.overhaul.feign.TicketFeign;
import com.koron.order.overhaul.mapper.OverhaulOrderMapper;
import com.koron.order.overhaul.notified.OverhaulOrderNotifyHolder;
import com.koron.order.overhaul.service.*;
import com.koron.order.overhaul.utils.CommonUtils;
import com.koron.order.overhaul.utils.Constants;
import com.koron.order.overhaul.utils.OverhaulConstants;
import com.koron.order.overhaulExperimentRel.bean.po.OverhaulExperimentRelPo;
import com.koron.order.overhaulExperimentRel.service.OverhaulExperimentRelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;

/**
 * (OverhaulOrderBean)表服务实现类
 *
 * @author twcao
 * @since 2021-09-29 09:49:24
 */
@Slf4j
@Service
public class OverhaulServiceImpl implements OverhaulOrderService {

    @Autowired
    private OverhaulOrderMajorService majorService;

    @Autowired
    private OverhaulOrderMajorFormService formService;

    @Autowired
    private OverhaulOrderReadyService readyService;

    @Autowired
    private OverhaulOrderItemService itemService;

    @Autowired
    private OverhaulOrderItemParamsService paramsService;

    @Autowired
    private OrderDispatchService dispatchService;

    @Autowired
    private OrderDispatchTeamService dispatchTeamService;

    @Autowired
    private OrderDispatchWorkerService dispatchWorkerService;

    @Autowired
    private OrderWorkDeptService workDeptService;

    @Autowired
    private OrderInstructionService instructionService;

    @Autowired
    private OrderExecuteInfoService executeInfoService;

    @Autowired
    private OrderExecuteService executeService;

    @Autowired
    private OrderGradeService gradeService;

    @Autowired
    private OverhaulOrderReportService reportService;

    @Autowired
    private OverhaulOrderNotifyHolder orderNotifyHolder;

    @Autowired
    private OverhaulOrderConvertor convertor;

    @Autowired
    private OrderExecutePartService partService;

    @Autowired
    private EquipmentFeign equipmentFeign;

    @Autowired
    private PlanIssueFeign issueFeign;

    @Autowired
    private GradeFeign gradeFeign;

    @Autowired
    private TicketFeign ticketFeign;

    @Autowired
    private WorkFlowHandler workFlowHandler;

    @Autowired
    private OverhaulExperimentRelService overhaulExperimentRelService;

    @Autowired
    private ExperimentService experimentService;

    /*工单的工作地点*/
    @Autowired
    OrderLocationService orderLocationService;

    @Override
    @TaskAnnotation("queryById")
    public OverhaulOrderDetailVO queryById(SessionFactory factory, String orderId) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        OverhaulOrderDetailVO detailVo = mapper.queryById(orderId);
        Assert.notNull(detailVo, "工单Id=" + orderId + "不存在");
        detailVo.setDispatch(queryDispatchInfoByOrderId(factory, orderId));
        List<OrderExecuteVo> orderExecuteVos = executeInfoService.queryListByOrderId(factory, orderId);
        List<OrderExecuteVO> orderExecuteVOS = convertor.commonExecuteVosToExecuteVos(orderExecuteVos);
        Map<String, List<OrderExecuteVO>> executesMap = orderExecuteVOS.stream().collect(groupingBy(OrderExecuteVO::getMajorId));
        detailVo.getMajors().stream().forEach(major -> {
            major.setExecutes(executesMap.get(major.getId()));
            List<OverhaulOrderMajorFormVO> forms = major.getForms();
            forms.stream().forEach(form -> {
                List<OverhaulOrderItemVO> itemDTOs = form.getItemDTOs();
                itemDTOs = itemDTOs.stream().filter(item->item.getMajorId().equals(major.getId()) && item.getFormId().equals(form.getId())).collect(Collectors.toList());
                itemDTOs.forEach(item -> item.setSigns(getSignsByItemIdAndOrderId(factory, item.getId(), item.getOverhaulId())));
                form.setItemDTOs((CommonUtils.listToTree(itemDTOs, OverhaulOrderItemVO.class)));
            });

            major.setInstructions(instructionService.queryByBizId(factory, major.getId()));
        });
        detailVo.setGrades(gradeService.getGradeByOrderId(factory, orderId));
//        if (StringUtils.equals(Constants.ORDER_SOURCE.PLAN_ORDER, detailVo.getSourceId())) {
            Equipment equipment = CommonUtils.ok(equipmentFeign.queryById(detailVo.getEquipmentId()));
            detailVo.setTypeId(equipment.getTypeId());
//        }
        //加入关联的实验报告信息
        OverhaulExperimentRelPo overhaulExperimentRelPo = new OverhaulExperimentRelPo();
        overhaulExperimentRelPo.setOverhaulId(orderId);
        //查询大修工单关联的试验工单列表
        List<OverhaulExperimentRelPo> relPos = overhaulExperimentRelService.queryList(factory, overhaulExperimentRelPo);
        if (CollectionUtils.isNotEmpty(relPos)) {
            List<String> experimentIds = relPos.stream().map(OverhaulExperimentRelPo::getExperimentId).collect(Collectors.toList());
            ExperimentQuery experimentQuery = new ExperimentQuery();
            experimentQuery.setExperimentIds(experimentIds);
            //查询具体试验工单列表信息
            List<ExperimentVo> experimentVos = experimentService.queryList(factory, experimentQuery);
            detailVo.setExperimentVoList(experimentVos);
        }
        //工作地点从表
        List<OrderLocationPo> orderLocationPos = orderLocationService.queryByOrderId(factory, orderId);
        detailVo.setOrderLocationList(orderLocationPos);

        return detailVo;
    }

    @Override
    public boolean saveOrUpdate(SessionFactory factory, OverhaulOrderBean bean) {
        Assert.notNull(bean, "大修工单不能为空");
        // 设置主键、状态、编号、删除标志等
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        bean.setId(StringUtils.isBlank(bean.getId()) ? CodeTools.getCode32() : bean.getId());
        bean.setStatus(Objects.isNull(bean.getStatus()) ? Constants.OverhaulStatus.DRAFT : bean.getStatus());
        bean.setCode(StringUtils.isBlank(bean.getCode()) ? CommonUtils.getCodeNo(OverhaulConstants.OVERHAUL_CODE_PREFIX, 3) : bean.getCode());
        CommonUtils.update(bean);
        if (CollectionUtils.isNotEmpty(bean.getOrderLocationList())){
            List<OrderLocationPo> orderLocationList = bean.getOrderLocationList();
            orderLocationList.stream().forEach(orderLocationPo -> orderLocationPo.setOrderId(bean.getId()));
            orderLocationService.insertBatch(factory,bean.getOrderLocationList());
        }
        return mapper.saveOrUpdate(bean) > 0;
    }

    @Override
    @TaskAnnotation("updateStatus")
    public String updateStatus(SessionFactory factory, OverhaulOrderBean bean) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        Assert.hasText(bean.getId(), "工单id不能为空");
        OverhaulOrderBean db = mapper.getById(bean.getId());
        db.setStatus(bean.getStatus());
        if (Constants.OverhaulStatus.PREPARE_REPORT.equals(bean.getStatus())) {
            db.setSubmitTime(bean.getSubmitTime());
        }
        mapper.saveOrUpdate(db);
        if (Constants.OverhaulStatus.EXECUTE.equals(bean.getStatus())) {
            if (StringUtils.equals(db.getSourceId(), Constants.OrderSource.PLAN_ORDER)) {
                // 如果保存的工单状态是执行中且由计划生成，表明为提交到执行中，则通知生产计划，改变计划状态，开始执行
                log.info("工单调用生产计划，通知计划修改计划状态[开始执行], 参数code = {}", db.getCode());
                Object obj = CommonUtils.ok(issueFeign.issueExecute(db.getCode()));
                log.info("工单调用生产计划，通知计划修改计划状态[开始执行], response = {}", JSON.toJSONString(obj));
            }
            createGradeOrder(factory, bean.getId());
        }
        if (Constants.OverhaulStatus.ARCHIVED.equals(bean.getStatus()) && StringUtils.equals(db.getSourceId(), Constants.OrderSource.PLAN_ORDER)) {
            // 如果保存的工单状态是编制大修报告，表明为提交到编制大修报告，则通知生产计划，改变计划状态，执行完成
            log.info("工单调用生产计划，通知计划修改计划状态[执行完成], 参数code = {}", db.getCode());
            Object obj = CommonUtils.ok(issueFeign.issueFinish(db.getCode()));
            log.info("工单调用生产计划，通知计划修改计划状态[执行完成], response = {}", JSON.toJSONString(obj));
        }
        if (Constants.OverhaulStatus.TO_ACCEPT.equals(bean.getStatus())) {
            OverhaulOrderDetailVO detail = queryById(factory, bean.getId());
            orderNotifyHolder.execute(factory, detail);
        }
        return bean.getId();
    }

    @Override
    public boolean update(SessionFactory factory, OverhaulOrderBean bean) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        return mapper.update(bean) > 0;
    }

    @Override
    @TaskAnnotation("updateState")
    public boolean updateState(SessionFactory factory, String id, String status) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        OverhaulOrderBean overhaulOrderBean = new OverhaulOrderBean();
        overhaulOrderBean.setId(id);
        overhaulOrderBean.setStatus(status);
        return mapper.update(overhaulOrderBean) > 0;
    }

    @Override
    @TaskAnnotation("deleteById")
    public OverhaulOrderDetailVO deleteById(SessionFactory factory, String orderId) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        OverhaulOrderDetailVO vo = queryById(factory, orderId);
        Assert.isTrue(!StringUtils.equals(vo.getSourceId(), Constants.OrderSource.PLAN_ORDER), "计划生成工单不允许删除");
        mapper.hidden(orderId);
        majorService.hiddenByOrderId(factory, orderId);
        formService.hiddenByOrderId(factory, orderId);
        readyService.hiddenByOrderId(factory, orderId);
        itemService.hiddenByOrderId(factory, orderId);
        paramsService.hiddenByOrderId(factory, orderId);
        orderNotifyHolder.execute(factory, vo);
        // 删除大修工单的工作流
        workFlowHandler.delete(orderId);
        return vo;
    }

    /*
      1、本单位用户能看到的数据范围：创建人及工单的设备管理单位在用户的组织权限之内的数据
      2、外单位用户能看到的数据范围：创建人及工单的作业单位在用户的组织权限之内的数据
    */
    @Override
    @TaskAnnotation("queryList")
    public List<OverhaulOrderBean> queryList(SessionFactory factory, OverhaulOrderQuery query) {
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);

        EamUser currUser = getCurrUser();
        if ("1".equalsIgnoreCase(currUser.getIsOutOrg())) {
            query.setDeptWorkList(getCurrUserOrgIds());
        } else {
            query.setDeptManageList(getCurrUserOrgIds());
        }

        query.setCurrAccount(ThreadLocalContext.get().getAccount());
        List<OverhaulOrderBean> list;
        // todo 设备台账向上归集查询
        if (query.isCollectionSearch()){
            list = collectionSearch(factory,query);
        }else {
            list = mapper.queryList(query);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            List<String> orderIds = list.stream().map(OverhaulOrderBean::getId).collect(Collectors.toList());
            //1.1 查询工单的作业单位
            List<OrderWorkDeptPo> orderWorkDeptPos = workDeptService.queryByOrderIds(factory, orderIds);
            //设置进列表
            if (CollectionUtils.isNotEmpty(orderWorkDeptPos)) {
                Map<String, List<OrderWorkDeptPo>> cond = orderWorkDeptPos.stream().collect(Collectors.groupingBy(OrderWorkDeptPo::getOrderId));
                for (OverhaulOrderBean overhaulOrderBean : list) {
                    overhaulOrderBean.setDeptWorkList(cond.getOrDefault(overhaulOrderBean.getId(), new ArrayList<>()));
                }
            }
        }

        return list;
    }

    /**
     * 向上归集查询
     * @param query
     * @param factory
     * @return
     */
    private List<OverhaulOrderBean> collectionSearch(SessionFactory factory, OverhaulOrderQuery query) {
        List<OverhaulOrderBean> result = new ArrayList<>();
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);
        List<String> childrens = new ArrayList<>();
        getAllChildrenEquipmentIds(mapper, Arrays.asList(query.getEquipmentId()), childrens);
        childrens.add(query.getEquipmentId());
        int batch = 50;
        int totalSize = childrens.size();
        List<List<String>> collect = IntStream.iterate(0, i -> i + batch)
                .limit((totalSize + batch - 1) / batch)
                .mapToObj(start -> childrens.stream().skip(start).limit(batch).collect(Collectors.toList()))
                .collect(Collectors.toList());
        // 获取所有的设备id
        List<String> ids = collect.stream().flatMap(Collection::parallelStream).collect(Collectors.toList());

        // 获取大修工单id、设备id
        List<Map<String,Object>> overhauls = mapper.getAllOverhaulIds();
        List<String> equipmentIds = overhauls.stream().map(m -> (String) m.get("equipmentId")).collect(Collectors.toList());
        Collection<String> intersection = CollectionUtils.intersection(ids, equipmentIds);

        List<String> overallIds = new ArrayList<String>();
        if (CollectionUtils.isNotEmpty(intersection)){
            intersection.forEach(i->{
                overhauls.forEach(o->{
                    if (i.equals(o.get("equipmentId"))){
                        overallIds.add(o.get("id").toString());
                    }
                });

            });
        }

        // 按条件分页查询
        query.prefixOrders("overhaul",null);
        PageHelper.startPage(query.getPage(), query.getPageSize(), query.getOrderBy());
        List<OrderItem> orders = query.getOrders();
        query.setEquipmentId(null);
        query.setIds(overallIds);

        result = mapper.queryList(query);

        PageHelper.clearPage();
        return result;
    }

    /**
     * 根据当前的设备id获取到所有子类设备id
     * @param mapper
     * @param equipmentIds
     * @param result
     * @return
     */
    private List<String> getAllChildrenEquipmentIds(OverhaulOrderMapper mapper, List<String> equipmentIds, List<String> result) {
        if (CollectionUtils.isEmpty(equipmentIds)){
            return new ArrayList<>();
        }
        List<String> children = mapper.getAllChildrenEquipmentIds(equipmentIds);

        result.addAll(children);
        return getAllChildrenEquipmentIds(mapper, children, result);
    }

    /**
     * 保存或更新-草稿
     *
     * @param factory 会话
     * @param vo      提交的实体
     * @return 返回详情
     */
    @Override
    @TaskAnnotation("draft")
    public String draft(SessionFactory factory, OverhaulOrderDraftVO vo) {
        vo.setId(StringUtils.isBlank(vo.getId()) ? CodeTools.getCode32() : vo.getId());
        vo.setStatus(vo.getStatus() == null ? Constants.OverhaulStatus.DRAFT : vo.getStatus());
        orderNotifyHolder.execute(factory, vo);
        return vo.getId();
    }

    /**
     * 可提交人员列表
     *
     * @return
     */
    @Override
    @TaskAnnotation("allowSubmit")
    public List<String> allowSubmit(SessionFactory factory, String orderId) {
        List<String> operator = new ArrayList<>();
        OverhaulOrderDetailVO vo = queryById(factory, orderId);
        OrderDispatchVO dispatch = vo.getDispatch();
        if (Objects.isNull(dispatch)) {
            return operator;
        }
        operator.add(Constants.YesOrNo.YES.equals(dispatch.getIsOut()) ? dispatch.getOutLeader() : dispatch.getLeader());
        List<OrderDispatchTeamVO> teams = dispatch.getTeams();
        if (CollectionUtils.isEmpty(teams)) {
            return operator;
        }
        List<String> workers = teams.stream()
                .filter(team -> CollectionUtils.isNotEmpty(team.getWorkers()))
                .flatMap(team -> team.getWorkers().stream())
                .map(OrderDispatchWorker::getWorker)
                .collect(Collectors.toList());
        operator.addAll(workers);
        return operator;
    }

    /**
     * 新增或保存作业指导书
     *
     * @param factory      会话
     * @param instructions 作业指导书
     * @return
     */
    @Override
    @TaskAnnotation("saveOrUpdateInstruction")
    public boolean saveOrUpdateInstruction(SessionFactory factory, List<OrderInstructionBean> instructions) {
        if (CollectionUtils.isEmpty(instructions)) {
            return true;
        }
        Stream.iterate(0, i -> i + 1).limit(instructions.size()).forEach(i -> {
            OrderInstructionBean instruction = instructions.get(i);
            instruction.setOrderType(OrderType.OVERHAUL);
            instruction.setSort(i + 1);
        });
        instructionService.insertBatch(factory, instructions);
        return true;
    }

    /**
     * 删除作业指导书
     *
     * @param factory
     * @param instructionId
     * @return
     */
    @Override
    @TaskAnnotation("deleteInstruction")
    public boolean deleteInstruction(SessionFactory factory, String instructionId) {
        return instructionService.deleteById(factory, instructionId) > 0;
    }

    /**
     * 保存或更新-待派工
     *
     * @param factory 会话
     * @param vo      提交的实体
     * @return 返回详情
     */
    @Override
    @TaskAnnotation("dispatch")
    public String dispatch(SessionFactory factory, OrderDispatchVO vo) {
        Assert.hasText(vo.getOrderId(), "工单id不能为空");
        orderNotifyHolder.execute(factory, vo);
        // 如果只是修改，直接返回id
        return StringUtils.isNotBlank(vo.getId()) ? vo.getId() : dispatchService.queryByOrderId(factory, vo.getOrderId()).getId();
    }

    /**
     * 根据工单id查询派工信息详情
     *
     * @param factory 会话
     * @param orderId 工单id
     * @return
     */
    @Override
    @TaskAnnotation("queryDispatchInfoByOrderId")
    public OrderDispatchVO queryDispatchInfoByOrderId(SessionFactory factory, String orderId) {
        OrderDispatch dispatch = dispatchService.queryByOrderId(factory, orderId);
        if (Objects.isNull(dispatch)) {
            return null;
        }
        OrderDispatchVO dispatchVO = convertor.dispatchBeanToVo(dispatch);
        List<OrderDispatchTeam> teams = dispatchTeamService.queryByDispatchId(factory, dispatchVO.getId());
        // 工作班组
        List<OrderDispatchTeamVO> teamVos = convertor.dispatchTeamBeansToVos(teams);
        // 工作班成员
        List<OrderDispatchWorker> workers = dispatchWorkerService.queryByOrderId(factory, orderId);
        // 工作单位
        List<OrderWorkDeptPo> workerDepts = workDeptService.queryByOrderId(factory, orderId);
        Map<String, List<OrderDispatchWorker>> workerMaps = workers.stream().collect(groupingBy(OrderDispatchWorker::getTeamId));
        Map<String, List<OrderWorkDeptPo>> workerDeptMaps = workerDepts.stream().collect(groupingBy(OrderWorkDeptPo::getTeamId));
        teamVos.stream().forEach(team -> {
            team.setWorkers(workerMaps.get(team.getId()));
            team.setWorkerDept(workerDeptMaps.get(team.getId()));
        });
        dispatchVO.setTeams(teamVos);
        return dispatchVO;
    }

    /**
     * 删除派工信息
     *
     * @param factory 会话
     * @param orderId 工单id
     * @return
     */
    @Override
    @TaskAnnotation("deleteDispatchInfo")
    public boolean deleteDispatchInfo(SessionFactory factory, String orderId) {
        dispatchService.deleteByOrderId(factory, orderId);
        dispatchTeamService.deleteByOrderId(factory, orderId);
        dispatchWorkerService.deleteByOrderId(factory, orderId);
        return true;
    }

    /**
     * 保存或更新-待执行
     *
     * @param factory 会话
     * @param bean    实体
     * @return
     */
    @Override
    @TaskAnnotation("toExecute")
    public boolean toExecute(SessionFactory factory, OverhaulOrderBean bean) {
        Assert.hasText(bean.getId(), "工单id不能为空");
        return orderNotifyHolder.execute(factory, bean);
    }

    /**
     * 保存或更新-执行中
     *
     * @param factory 会话
     * @param vo      执行信息
     * @return
     */
    @Override
    @TaskAnnotation("saveExecuteInfo")
    public String saveExecuteInfo(SessionFactory factory, OrderExecuteVO vo) {
        Assert.isTrue(vo != null && StringUtils.isNotBlank(vo.getOrderId()), "工单id不能为空");
        String executeId = StringUtils.isBlank(vo.getId()) ? CodeTools.getCode32() : vo.getId();
        vo.setId(executeId);
        OverhaulOrderMajorVO majorVO = new OverhaulOrderMajorVO();
        List<OrderExecuteVO> executes = new ArrayList<>();
        executes.add(vo);
        majorVO.setExecutes(executes);
        majorVO.setOverhaulId(vo.getOrderId());
        orderNotifyHolder.execute(factory, majorVO);
        return executeId;
    }

    /**
     * 保存或更新-执行中-表单
     *
     * @param factory 会话
     * @param vo      表单
     * @return 表单id
     */
    @Override
    @TaskAnnotation("execute")
    public OverhaulOrderMajorFormVO execute(SessionFactory factory, OverhaulOrderMajorFormVO vo) {
        Assert.hasText(vo.getOverhaulId(), "工单id不能为空");
        OverhaulOrderMajorVO majorVO = new OverhaulOrderMajorVO();
        List<OverhaulOrderMajorFormVO> forms = new ArrayList<>();
        vo.setId(StringUtils.isBlank(vo.getId()) ? CodeTools.getCode32() : vo.getId());
        forms.add(vo);
        majorVO.setForms(forms);
        majorVO.setOverhaulId(vo.getOverhaulId());
        orderNotifyHolder.execute(factory, majorVO);
        return vo;
    }

    /**
     * 根据执行id删除执行信息
     *
     * @param factory   会话
     * @param executeId 执行id
     * @return
     */
    @Override
    @TaskAnnotation("deleteExecuteInfoByExecuteId")
    public boolean deleteExecuteInfoByExecuteId(SessionFactory factory, String executeId) {
        executeService.deleteById(factory, executeId);
        partService.deleteByOrderExecuteId(factory, executeId);
        return true;
    }

    /**
     * 根据工单id查询执行信息列表
     *
     * @param factory 会话
     * @param orderId 工单
     * @return
     */
    @Override
    @TaskAnnotation("queryExecuteInfoByOrderId")
    public List<OverhaulOrderMajorVO> queryExecuteInfoByOrderId(SessionFactory factory, String orderId) {
        OverhaulOrderDetailVO detail = queryById(factory, orderId);
        return detail.getMajors();
    }

    /**
     * 更新数据记录变量
     *
     * @param factory 会话
     * @param vo      参数
     * @return
     */
    @Override
    @TaskAnnotation("updateParam")
    public boolean updateParam(SessionFactory factory, OverhaulOrderItemParamsVO vo) {
        paramsService.saveOrUpdate(factory, vo);
        return true;
    }

    /**
     * 签名
     *
     * @param factory
     * @param signBean
     * @return
     */
    @Override
    @TaskAnnotation("sign")
    public boolean sign(SessionFactory factory, OrderSignBean signBean) {
        OrderSignMapper signMapper = factory.getMapper(OrderSignMapper.class);
        Assert.isTrue(StringUtils.isNoneBlank(signBean.getItemId(), signBean.getSigner()), "签名项Id和签名不能为空");
        // 如果已经签名，则删除之前的签名
        OrderSignBean query = new OrderSignBean();
        query.setSigner(signBean.getSigner());
        query.setItemId(signBean.getItemId());
        List<OrderSignBean> orderSignBeans = signMapper.queryList(query);
        orderSignBeans.stream().forEach(sign -> signMapper.deleteById(sign.getId()));
        signBean.setOrderType(OrderType.OVERHAUL);
        signBean.setId(StringUtils.isBlank(signBean.getId()) ? CodeTools.getCode32() : signBean.getId());
        signMapper.insert(signBean);
        return true;
    }

    /**
     * 根据作业项获取签名
     *
     * @param factory
     * @param itemId
     * @return
     */
    @Override
    public List<OrderSignBean> getSignsByItemId(SessionFactory factory, String itemId) {
        OrderSignMapper signMapper = factory.getMapper(OrderSignMapper.class);
        OrderSignBean query = new OrderSignBean();
        query.setItemId(itemId);
        return signMapper.queryList(query);
    }

    @Override
    public List<OrderSignBean> getSignsByItemIdAndOrderId(SessionFactory factory, String itemId, String orderId) {
        OrderSignMapper signMapper = factory.getMapper(OrderSignMapper.class);
        OrderSignBean query = new OrderSignBean();
        query.setItemId(itemId);
        query.setOrderId(orderId);
        return signMapper.queryList(query);
    }

    /**
     * 设置作业过程项的值
     *
     * @param factory 会话
     * @param item    作业过程项
     * @return 是否成功
     */
    @Override
    @TaskAnnotation("itemValue")
    public boolean itemValue(SessionFactory factory, ItemValueVO item) {
        Assert.isTrue(item != null && StringUtils.isNoneBlank(item.getItemId(), item.getKey(), item.getValue()), "作业过程项不能为空");
        OverhaulOrderItemBean bean = itemService.queryById(factory, item.getItemId());
        Assert.notNull(bean, "作业过程项不能为空");
        try {
            BeanUtils.setProperty(bean, item.getKey(), item.getValue());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        List<OverhaulOrderItemBean> beans = new ArrayList<>();
        beans.add(bean);
        itemService.saveOrUpdate(factory, beans);
        return true;
    }

    /**
     * 保存编制大修报告
     *
     * @param factory 会话
     * @param report  编制大修报告
     * @return
     */
    @Override
    @TaskAnnotation("prepareReport")
    public boolean prepareReport(SessionFactory factory, OverhaulOrderReportBean report) {
        return orderNotifyHolder.execute(factory, report);
    }

    /**
     * 根据工单id查询编制大修报告
     *
     * @param factory 会话
     * @param orderId 工单id
     * @return 编制大修报告详情
     */
    @Override
    @TaskAnnotation("getPrepareReportByOrderId")
    public OverhaulOrderReportBean getPrepareReportByOrderId(SessionFactory factory, String orderId) {
        return reportService.queryByOrderId(factory, orderId);
    }

    /**
     * 待验收-提供工作流
     *
     * @param factory 会话
     * @param orderId 工单id
     * @return
     */
    @Override
    @TaskAnnotation("toAccept")
    public boolean toAccept(SessionFactory factory, String orderId) {
        OverhaulOrderDetailVO detail = queryById(factory, orderId);
        return orderNotifyHolder.execute(factory, detail);
    }

    /**
     * 工单接收完成，完成工作流审核
     *
     * @param factory 会话
     * @param orderId 工单id
     * @return
     */
    @Override
    @TaskAnnotation("toAcceptFinish")
    public boolean toAcceptFinish(SessionFactory factory, String orderId) {
        Assert.hasText(orderId, "工单id不能为空");
        OverhaulOrderQuery query = new OverhaulOrderQuery();
        query.setId(orderId);
        List<OverhaulOrderBean> orders = queryList(factory, query);
        Assert.notEmpty(orders, "工单不存在");
        OverhaulOrderBean order = orders.get(0);
        // 工作流结束后，状态调整为"已归档"
        order.setStatus(Constants.OverhaulStatus.ARCHIVED);
        saveOrUpdate(factory, order);
        if (Constants.OverhaulStatus.ARCHIVED.equals(order.getStatus()) && StringUtils.equals(order.getSourceId(), Constants.OrderSource.PLAN_ORDER)) {
            // 如果保存的工单状态是编制大修报告，表明为提交到编制大修报告，则通知生产计划，改变计划状态，执行完成
            log.info("工单调用生产计划，通知计划修改计划状态[执行完成], 参数code = {}", order.getCode());
            Object obj = CommonUtils.ok(issueFeign.issueFinish(order.getCode()));
            log.info("工单调用生产计划，通知计划修改计划状态[执行完成], response = {}", JSON.toJSONString(obj));
        }
        return true;
    }

    /**
     * 创建分级分项验收单
     *
     * @param factory 会话
     * @param orderId 工单id
     */
    @Override
    public void createGradeOrder(SessionFactory factory, String orderId) {
        // 4、分级分项验收单
        if (CollectionUtils.isEmpty(gradeService.getGradeByOrderId(factory, orderId))) {
            //只在初始化的时候保存，以后只能在分级分项验收中修改
            OverhaulOrderDetailVO vo = queryById(factory, orderId);
            Equipment equipment = CommonUtils.ok(equipmentFeign.queryById(vo.getEquipmentId()));
            // 设备分类，一般一个分类下只有一个标准，但一个标准下会有多个标准项
            String typeId = equipment.getTypeId();
            List<GradeDTO> gradeDTOs = getGrade(typeId);
            // 根据专业找负责人
            List<OrderDispatchTeamVO> teams = vo.getDispatch().getTeams();
            Map<String, OrderDispatchTeamVO> joberMap = teams.stream().collect(Collectors.toMap(OrderDispatchTeamVO::getMajor, team -> team, (key1, key2) -> key2));
            List<OrderGradeBean> grades = new ArrayList<>();
            gradeDTOs.stream().forEach(gradeDto -> {
                List<GradeItem> gradeItems = gradeDto.getItems();
                List<OrderGradeBean> orderGrades = gradeItems.stream().map(gradeItem -> {
                    OrderGradeBean gradeBean = new OrderGradeBean();
                    CommonUtils.update(gradeBean, vo.getUpdateBy(), vo.getUpdateByName());
                    CommonUtils.update(gradeBean);
                    gradeBean.setId(StringUtils.isBlank(gradeBean.getId()) ? CodeTools.getCode32() : gradeBean.getId());
                    gradeBean.setOrderId(vo.getId());
                    gradeBean.setCode(StringUtils.isBlank(gradeBean.getCode()) ? CodeTools.getCodeNo(vo.getCode() + Constants.GRADE_CODE_SPLIT, 2) : gradeBean.getCode());
                    gradeBean.setTitle(gradeItem.getName());
                    gradeBean.setName(gradeItem.getName());
                    gradeBean.setMajor(gradeItem.getMajor());
                    OrderDispatchTeamVO team = joberMap.get(gradeItem.getMajor());
                    if (Objects.isNull(team)) {
                        // 在后续filter中，过滤空对象
                        log.warn("专业 = {} 无对应的现场负责人，不会生成分级分项验收单", gradeItem.getMajor());
                        return null;
                    }
                    gradeBean.setJober(team.getJober());
                    gradeBean.setJoberName(team.getJoberName());
                    gradeBean.setStandardId(gradeDto.getId());
                    gradeBean.setStandardItemId(gradeItem.getId());
                    gradeBean.setLevel(gradeItem.getLevel());
                    gradeBean.setContext(gradeItem.getContext());
                    gradeBean.setContextStandard(gradeItem.getContextStandard());
                    gradeBean.setStatus(Constants.OrderGradeStatus.DRAFT);
                    gradeBean.setDeptId(vo.getDeptId());
                    return gradeBean;
                }).filter(row -> !Objects.isNull(row)).collect(Collectors.toList());
                grades.addAll(orderGrades);
            });
            if (!CollectionUtils.isEmpty(grades)) {
                gradeService.saveOrUpdate(factory, grades);
            }
        }
    }

    private List<GradeDTO> getGrade(String typeId) {
        String appId = ThreadLocalContext.get().getAppId();
        GradeQuery query = new GradeQuery();
        query.setAppid(appId);
        query.setTypeId(typeId);
        // 查询应用下，该分类的所有分级分项标准
        return CommonUtils.ok(gradeFeign.list(query));
    }

    /**
     * 工作流更新
     *
     * @param factory
     * @param redirectQuery
     */
    @Override
    @TaskAnnotation("workflowUpdate")
    public Boolean workflowUpdate(SessionFactory factory, RedirectQuery redirectQuery) {
        Integer operation = redirectQuery.getOperation();
        OverhaulOrderBean vo = JSON.parseObject(redirectQuery.getFormVariables(), OverhaulOrderBean.class);
        switch (operation) {
            case 256: // 撤回
            case 1: // 驳回
                // 驳回的节点编号
                // 驳回到编制大修报告
                vo.setStatus(Constants.OverhaulStatus.PREPARE_REPORT);
                updateState(factory, vo.getId(), vo.getStatus());
                break;
            case 32: // 同意
                vo.setStatus(Constants.OverhaulStatus.TO_ACCEPT);
                updateState(factory, vo.getId(), vo.getStatus());
                break;
        }
        return true;
    }

    @Override
    @TaskAnnotation("queryTicketByOrderId")
    public List<Integer> queryTicketByOrderId(SessionFactory factory, String orderId) {
        Assert.hasText(orderId, "工单id不能为空");
        List<WorkTicket> tickets = CommonUtils.ok(ticketFeign.queryTicketByOrderId(orderId));
        List<Integer> status = tickets.stream().map(WorkTicket::getStatus).distinct().sorted().collect(Collectors.toList());
        return status;
    }

    @Override
    @TaskAnnotation("queryTicketListByOrderId")
    public List<WorkTicket> queryTicketListByOrderId(SessionFactory factory, String orderId) {
        Assert.hasText(orderId, "工单id不能为空");
        List<WorkTicket> tickets = CommonUtils.ok(ticketFeign.queryTicketByOrderId(orderId));
        return tickets;
    }

    @Override
    @TaskAnnotation("queryExperimentVoList")
    public List<ExperimentVo> queryExperimentVoList(SessionFactory factory, OverhaulExperimentQuery query) {

        //加入关联的实验报告信息
        OverhaulExperimentRelPo overhaulExperimentRelPo = new OverhaulExperimentRelPo();
        String overhaulId = query.getOverhaulId();
        overhaulExperimentRelPo.setOverhaulId(overhaulId);
        //查询大修工单关联的试验工单列表
        List<OverhaulExperimentRelPo> relPos = overhaulExperimentRelService.queryList(factory, overhaulExperimentRelPo);
        if (CollectionUtils.isNotEmpty(relPos)) {
            List<String> experimentIds = relPos.stream().map(OverhaulExperimentRelPo::getExperimentId).distinct().collect(Collectors.toList());
            ExperimentQuery experimentQuery = new ExperimentQuery();
            experimentQuery.setExperimentIds(experimentIds);
            //查询具体试验工单列表信息
            List<ExperimentVo> experimentVos = experimentService.queryList(factory, experimentQuery);
            if (CollectionUtils.isNotEmpty(experimentVos)){
                experimentVos  = experimentVos.stream().filter(e-> e.getOverhaulId().equals(overhaulId)).collect(Collectors.toList());
            }
            return experimentVos;
        }
        return new ArrayList<>();
    }

    @Override
    @TaskAnnotation("deprecated")
    public String deprecated(SessionFactory factory, String orderId) {

        //作废工单
        OverhaulOrderMapper mapper = factory.getMapper(OverhaulOrderMapper.class);

        OverhaulOrderBean overhaulOrderBean = new OverhaulOrderBean();
        overhaulOrderBean.setId(orderId);
        overhaulOrderBean.setStatus(com.koron.order.overhaul.bean.dto.OverhaulStatus.DEPRECATED.getStatus());

        mapper.update(overhaulOrderBean);
        return "ok";
    }

    @Override
    @TaskAnnotation("getExecuteInfoByOrderId")
    public List<OrderExecuteVO> getExecuteInfoByOrderId(SessionFactory factory, String orderId) {
        List<OrderExecuteVo> orderExecuteVos = executeInfoService.queryListByOrderId(factory, orderId);
        List<OrderExecuteVO> orderExecuteVOS = convertor.commonExecuteVosToExecuteVos(orderExecuteVos);
        return orderExecuteVOS;
    }
}
